import { VuexModule, Module, Mutation, getModule, Action } from 'vuex-module-decorators'
import store from '@/store'
import Vue from 'vue'
import router from '@/router/handleRoute'
import { microRouter, instance } from '@/microPage/webchat/main'
import orderBy from 'lodash/orderBy'
import {
  WebchatList,
  WebchatListStatusObj,
  WebchatReplyMsgObj,
  WebchatCardInfoObj,
  WebchatChatInfoObj,
  WebchatMessageListObj,
  FileUploadProessObj,
  SendLastContentObj
} from '@/store/modules/webchat/interface'
import { commonAction, deepClone, formatStamp } from '@/utils/common'
import { Message } from 'element-ui'
export interface WebchatState {
  webchatList: object
  webchatInfo: object
  webchatMessage: object
  webchatTodoMessageChange: object
  webchatFileUpload: object
  webchatEmoji: object
  webchatSendLastContent: object
  webchatErrorCode: object,
  msgBoxScrollBottom: any // 滚动条距离底部距离
  unreadmessages: any // 未读消息数
  unreadmessagesid: any // 当前未读id
  showAgentTypeNotice: any
}
@Module({ dynamic: true, store, name: 'webchat', namespaced: false })

class Webchat extends VuexModule implements WebchatState {
  public webchatList: any = {} // 卡片列表
  public webchatMessage: any = { // 消息列表
    webchat_todo: {},
    webchat_close: {},
    webchat_leaveMessage: {},
    webchat_queue: {},
    webchatDateCenter: {}
  }

  public webchatUnDealNum: number = 0 // 在线排队数
  public leaveNume: number = 0 // 留言加减数
  public quickReplyList: any = [] // 快捷回复列表
  public webchatErrorCode = {} // 在线错误码
  public webchatInfo = {} // 会话详情
  public webchatTodoMessageChange = {} // 待处理消息列表改变
  public webchatFileUpload: any = {}
  public webchatEmoji: any = {} // emoji配置
  public webchatSendLastContent: any = {} // 发送的最后内容
  public webchatPreLoadedObj: any = {} // 访客预输入消息
  public webchatOverTimeInfoList: any = [] // 已经触发超时提醒的会话
  public messageKeyWords: any = [] // 高级搜索搜索内容
  public agentData: {} | null = null // 智能辅助数据

  // 访客端未读消息参数
  public msgBoxScrollBottom = 0 // 滚动条距离底部距离
  public unreadmessages = 0 // 未读消息数
  public unreadmessagesid = '' // 当前未读id
  public showAgentTypeNotice = false

  @Action
  public async webchatCommonAction (parame: object) {
    return commonAction(parame).then(resp => {
      if (resp && resp.success) {
        return resp
      }
    })
  }

  @Action
  public async getWebchatList (parame: any) { // 获取卡片列表action
    return commonAction(parame).then(resp => {
      const submenu = parame.data.submenu
      if (resp && resp.success && submenu) {
        this.SET_WEBCHAT_LIST({ list: resp.list, submenu })
        WebchatModule.SORTLISTBY_TYPE(parame.data.submenu) // 更新会话顺序
        return resp
      }
    })
  }

  @Mutation
  public async SET_WEBCHAT_LIST (obj: WebchatList) { // 卡片列表
    if (obj.newChat) { // 新会话需要把新的会话放到webchatList中
      if (!this.webchatList[obj.submenu]) {
        Vue.set(this.webchatList, obj.submenu, {})
      } else {
        this.webchatList[obj.submenu].unshift(obj.list)
      }
    } else {
      Vue.set(this.webchatList, obj.submenu, obj.list)
    }
  }

  @Mutation
  public async UPDATE_WEBCHAT_LIST_STATUS (obj: WebchatListStatusObj) { // 更新卡片列表信息
    if (WebchatModule.webchatList.webchat_todo) {
      WebchatModule.webchatList.webchat_todo.forEach((item: any) => {
        if (item._id === obj.data.sessionId) {
          Vue.set(item, 'isVisitorBreak', obj.isVisitorBreak) // 更新卡片上的访客状态
        }
      })
    }
  }

  @Action
  public async webchatReplyMsg (parame: any) { // 发送消息
    const data = parame.data
    return commonAction(parame).then(resp => {
      if (resp && resp.success) {
        data.sendStatus = 'success'
        data.createTime = formatStamp(resp.createTimestamp || new Date().getTime())
        data._id = resp.messageId
      } else {
        data.sendStatus = 'fail'
        if (resp.code.indexOf('wx_') > -1) {
          Message({ message: this.webchatErrorCode[resp.code], type: 'error', duration: 5 * 1000 })
        } else {
          Message({ message: resp.message, type: 'error', duration: 5 * 1000 })
        }
      }
      this.SET_WEBCHAT_REPLYMSG(data)
    }).catch(error => {
      data.sendStatus = 'fail'
      this.SET_WEBCHAT_REPLYMSG(data)
      console.log(error)
    })
  }

  @Mutation
  public async SET_WEBCHAT_REPLYMSG (obj: WebchatReplyMsgObj) { // 发送消息mutation
    const currentMessageList = this.webchatMessage.webchat_todo[obj.sessionId]
    if (obj.sendStatus === 'success' || obj.sendStatus === 'fail') { // 发送消息成功or失败
      if (currentMessageList) {
        currentMessageList.forEach((item: any, index: any) => {
          if (item.timeStamp === obj.timeStamp) { // 找到当前发送的消息
            if (obj.sendStatus === 'success') { // 发送消息成功
              const setDataArr = ['sendStatus', '_id', 'createTime', 'messageId'] // 需要set到历史消息的值
              setDataArr.forEach(setItem => {
                if (item.contentType === 'file') {
                  Vue.set(currentMessageList[index], 'content', obj.content) // 改变历史消息的值
                }
                Vue.set(currentMessageList[index], setItem, obj[setItem]) // 改变历史消息的值
              })
              // 更新卡片上最后一条消息
              WebchatModule.updateWebchatCardInfo({ obj, from: 'agent' })
              WebchatModule.SORTLISTBY_TYPE('webchat_todo') // 更新会话顺序
            } else { // 发送消息失败
              Vue.set(currentMessageList[index], 'sendStatus', obj.sendStatus) // 改变消息状态
            }
          }
        })
      }
    } else { // 发送中
      this.webchatMessage.webchat_todo[obj.sessionId].push(obj)
    }
  }

  @Action
  public async updateWebchatCardInfo (data: WebchatCardInfoObj) { // 更新卡片信息
    const currentWebchatList = this.webchatList.webchat_todo
    if (currentWebchatList) {
      currentWebchatList.forEach((item: any) => {
        if (item._id === data.obj.sessionId) { // 找到当前的会话
          const { content, contentType }: any = data.obj
          const lastMessage = { contentType, content, lastMessageFrom: data.from }
          Vue.set(item, 'lastMessage', lastMessage) // 更新卡片最后一条消息
          if (data.from === 'agent') { // 更新座席最后回复的时间
            Vue.set(item, 'lastAgentMessageTimestamp', (data.obj as any).createTime ? (data.obj as any).createTime : data.obj.timeStamp)
            Vue.set(item, 'visitorStartWaitTimestamp', 0) // 座席回复消息需要把访客等待时长请0
            Vue.set(item, 'agentReplyMessageCount', (item.agentReplyMessageCount ? item.agentReplyMessageCount : 0) + 1) // 更新客户消息数
          } else {
            Vue.set(item, 'lastMessageTimestamp', data.obj.lastMessageTimestamp) // 更新最新消息时间
            Vue.set(item, 'visitorStartWaitTimestamp', data.obj.visitorStartWaitTimestamp) // 更新访客等待时长
            Vue.set(item, 'visitorMessageCount', (item.visitorMessageCount ? item.visitorMessageCount : 0) + 1) // 更新访客消息数
          }
        }
      })
    }
  }

  @Action
  public async queryChatInfoById (parame: any) { // 获取卡片详情action
    return commonAction(parame).then(resp => {
      if (resp && resp.success) {
        this.SET_WEBCHAT_CHATEINFO(resp.chatSession)
        return resp
      }
    })
  }

  @Mutation
  public async SET_WEBCHAT_CHATEINFO (obj: WebchatChatInfoObj) { // 获取卡片详情mutation
    const currentWebchatInfo = this.webchatInfo[obj._id]
    if (currentWebchatInfo && currentWebchatInfo.showHistoryBtn) { // 保留自定义属性
      obj.showHistoryBtn = currentWebchatInfo.showHistoryBtn
    }
    Vue.set(this.webchatPreLoadedObj, obj._id, this.webchatPreLoadedObj[obj._id] || {})
    Vue.set(this.webchatInfo, obj._id, obj)
  }

  @Action
  public async queryWebchatHistory (parame: any) { // 获取会话消息历史
    const sessionId = JSON.parse(JSON.stringify(parame.data._id)) // 当前会话ID
    const isNewSession = parame.data.isNewSession
    const webchatType = parame.data.webchatType
    delete parame.data._id
    delete parame.data.isNewSession
    delete parame.data.webchatType
    return commonAction(parame).then(resp => {
      if (resp && resp.success) {
        const messageList = resp.messageList.reverse()
        messageList.forEach((item: any) => {
          if (item.contentType === 'voice') {
            Vue.set(item, 'play', false)
          }
        })
        this.SET_WEBCHAT_MESSAGE_LIST({ list: messageList, sessionId, isNewSession, webchatType }) // 以会话为维度存消息历史
        return resp
      }
    })
  }

  @Mutation
  public async SET_WEBCHAT_MESSAGE_LIST (obj: WebchatMessageListObj) { // 消息列表mutation
    if (this.webchatMessage && this.webchatMessage[obj.webchatType] && !this.webchatMessage[obj.webchatType][obj.sessionId]) {
      Vue.set(this.webchatMessage[obj.webchatType], obj.sessionId, obj.list)
    } else {
      if (obj.isNewSession) { // 新会话接入
        Vue.set(this.webchatMessage[obj.webchatType], obj.sessionId, obj.list)
      } else {
        if (this.webchatMessage && this.webchatMessage[obj.webchatType]) {
          this.webchatMessage[obj.webchatType][obj.sessionId] = obj.list.concat(this.webchatMessage[obj.webchatType][obj.sessionId])
        }
      }
    }
    if (obj.list.length >= 20) {
      // 查询的是当前会话记录，且大于等于20条，展示查询历史的按钮
      Vue.set(this.webchatInfo[obj.sessionId], 'showHistoryBtn', true)
      Vue.set(this.webchatInfo[obj.sessionId], 'finishChatScroll', true)
    } else {
      // 当前长度小于20条，说明当前会话没有记录可查询，隐藏查询历史的按钮
      Vue.set(this.webchatInfo[obj.sessionId], 'showHistoryBtn', false)
      Vue.set(this.webchatInfo[obj.sessionId], 'finishChatScroll', false)
    }
  }

  @Mutation
  public async SET_WEBCHAT_MESSAGE_CHANGE (obj: any) { // 消息改变
    Vue.set(this.webchatTodoMessageChange, obj.sessionId, Math.random() + 1)
  }

  @Mutation
  public async CLOSE_WEBCHAT_SESSION ({ type, id }) { // 关闭会话
    this.webchatOverTimeInfoList = this.webchatOverTimeInfoList.filter(v => v !== id)
    if (this.webchatList[type]) {
      this.webchatList[type].forEach((item: any, index: number) => {
        if (item._id === id) {
          const webchatSession: any = window.sessionStorage
          const currentUrlObj = webchatSession.getItem('webchatTab') || ''
          if (currentUrlObj.indexOf(item._id) > -1) { // 如果当前会话不存在session存的当前会话url需清除
            webchatSession.setItem('webchatTab', '')
          }
          this.webchatList[type].splice(index, 1) // 从会话列表中删除当前会话
          if (type === 'webchat_todo') { // 只有在待处理列表中才去删除会话聊天记录
            delete this.webchatMessage[type][id]
          }
          delete this.webchatInfo[id] // 删除会话信息
          delete this.webchatSendLastContent[id] // 删除上次未发送的消息
        }
      })
    }
    WebchatModule.SORTLISTBY_TYPE('webchat_todo') // 更新会话顺序
    if (store.state.common.containerType && store.state.common.containerType === 'micro') { // 如果是微前端加载用微前端的router
      const microStore = (instance.$root as any).microStore
      if (microStore) {
        microStore.closeWebchatSession(id)
      }
      if (router.currentRoute.params.id === id) {
        microRouter.push({ path: '/im_workBench/index/' + type + '/empty' })
      }
    } else {
      if (router.currentRoute.params.id === id) {
        router.push({ path: '/im_workBench/index/' + type + '/empty' })
      }
    }
  }

  @Mutation
  public async SORTLISTBY_TYPE (activeNameType: any) { // 会话排序
    let list = this.webchatList[activeNameType] || []
    const currentUser = store.state.common.session.account.loginName + '@' + store.state.common.session.account._id
    const sortType = window.localStorage.getItem(currentUser + '/sortType') || 'lastMessageTimestamp' // 会话排序取值
    const topArr: any = []
    let cloneList: any = []
    list.forEach((item: any) => {
      if (item.setTopStatus === 'true') {
        topArr.push(item)
      } else {
        cloneList.push(item)
      }
    })
    cloneList = orderBy(cloneList, [(o: any) => {
      // 优先按照选择的方式排
      let aa = (o[sortType] || o.lastMessageTimestamp) || 0 // 最新消息
      if (sortType === 'visitorStartWaitTimestamp') { // 等待时长排序
        const now = new Date().getTime()
        let aTimer: number
        if (o.visitorStartWaitTimestamp > -1) {
          aTimer = o.visitorStartWaitTimestamp
        } else {
          aTimer = -1
        }
        aa = o.lastMessage && o.lastMessage.lastMessageFrom === 'customer' ? (now - aa) / 1000 : -1
      }
      if (sortType === 'manualTimestamp') { // 接入顺序排序
        aa = aa ? new Date(aa).getTime() : 0
      }
      return aa
    }, (o: any) => {
      // 如果没有对应值，按接入时间排序
      const aa = o.createTimestamp || 0
      return aa
    }], ['desc', 'desc'])
    list = topArr.concat(cloneList)
    Vue.set(this.webchatList, `${activeNameType}`, list)
  }

  @Action
  public async dealMsg (parame: any) { // 处理未读消息消费
    return commonAction(parame).then(resp => {
      if (resp && resp.success) {
        this.webchatList.webchat_todo.forEach((item: any) => { // 更新未读消息状态
          if (item._id === parame.data.sessionId) {
            Vue.set(item, 'leakNum', 0)
          }
        })
        this.DEAL_MSG(parame.data.sessionId)
      }
    })
  }

  @Mutation
  public DEAL_MSG (sessionId: string) { // 处理消费的消息
    const message = this.webchatMessage.webchat_todo[sessionId] || []
    if (message && message.length > 0) {
      message.forEach((item: any) => {
        if (item.type === 'in') {
          Vue.set(item, 'dealCustomerMsg', true)
        }
      })
    }
  }

  @Mutation
  public UPDATEDEALMSGSTATUS (sessionId: string) {
    const message = this.webchatMessage.webchat_todo[sessionId] || []
    if (message && message.length > 0) {
      message.forEach((item, index) => {
        if (item.type === 'out') {
          Vue.set(item, 'dealUserMsg', true)
        }
      })
    }
  }

  @Mutation
  public async FILE_UPLOAD_PROESS (obj: FileUploadProessObj) { // 上传文件进度条
    if (this.webchatMessage.webchat_todo[obj.sessionId]) {
      this.webchatMessage.webchat_todo[obj.sessionId].forEach((item: any) => {
        if (item.timeStamp === obj.timeStamp) {
          Vue.set(item, 'percent', obj.percent)
        }
      })
    }
  }

  @Mutation
  public async UPDATE_CUSTOMER_INFO (obj: any) { // 更新客户信息
    if (this.webchatInfo[obj.webchatDetails._id].visitorName) { // 更新会话消息
      Vue.set(this.webchatInfo[obj.webchatDetails._id], 'visitorName', obj.custName)
    }
    const listType = obj.type || 'webchat_todo'
    if (this.webchatList[listType]) { // 更新卡片列表
      const webchatList = this.webchatList[listType]
      webchatList.forEach(item => {
        if (item.visitorId === obj.webchatDetails.visitorId) {
          Vue.set(item, 'visitorName', obj.custName)
          Vue.set(item, 'labels', obj.labels)
        }
      })
    }
  }

  @Mutation
  public async SET_EMOJICONFIG (obj: any) { // 写入emoji数据
    this.webchatEmoji = obj
  }

  @Mutation
  public async SET_CHAT_VOICE_PLAY (obj: any) { // 更改语音播放状态
    this.webchatMessage[obj.tabType][obj.sessionId].forEach((item: any) => {
      if (item.createTimestamp === obj.createTimestamp) {
        Vue.set(item, 'play', obj.play)
      }
    })
  }

  @Mutation
  public async RESET_CHAT_VOICE_PLAY (obj: any) { // 重置其他正在播放的语音状态
    this.webchatMessage[obj.tabType][obj.sessionId].forEach((item: any) => {
      Vue.set(item, 'play', false)
    })
  }

  @Mutation
  public async SET_SENDLASTCONTENT (obj: SendLastContentObj) { // 写入输入框未输入的内容
    Vue.set(this.webchatSendLastContent, obj._id, obj.content)
  }

  @Mutation
  public async SET_WEBCHAT_ERROR (obj: any) { // 在线错误码
    this.webchatErrorCode = obj
  }

  @Mutation
  public async SET_QUICKREPLY_DATA (data: any) { // 在线常用语
    // 只展示前30条数据，个人在前，公共在后
    this.quickReplyList = data.agent.concat(data.common)
  }

  @Mutation
  public async UPDATE_PRELOADED_MSG (data: any) { // 更新在线访客预输入消息
    let flag = true
    if (data.content === '') {
      flag = false
    }
    if (!this.webchatPreLoadedObj[data.sessionId]) {
      Vue.set(this.webchatPreLoadedObj, data.sessionId, {})
    }
    Vue.set(this.webchatPreLoadedObj[data.sessionId], 'preLoadedInfo', data)
    Vue.set(this.webchatPreLoadedObj[data.sessionId], 'isShowPreLoaded', flag)
  }

  @Mutation
  public async SET_MESSAGEKEYWORKS (data: any) { // 高级搜索内容搜索
    this.messageKeyWords = data
  }

  @Mutation
  public ADD_WEBCHAT_OVERTIMEINFOLIST (sid: string) {
    this.webchatOverTimeInfoList.push(sid)
  }

  @Mutation
  public REMOVE_WEBCHAT_OVERTIMEINFOLIST (sid: string) {
    this.webchatOverTimeInfoList = this.webchatOverTimeInfoList.filter(v => v !== sid)
  }

  @Mutation
  public SET_WEBCHAT_UNDEALNUM (data: number) {
    this.webchatUnDealNum = data
  }

  @Mutation
  public SET_LEAVE_NUM (data: number) {
    this.leaveNume = data
  }

  @Mutation
  public async WITHDRAW_MSG (data: any) { // 消息撤回
    const currentSession = this.webchatMessage.webchat_todo[data.sessionId]
    const systemObj = {
      type: 'withdrawMsg',
      platform: data.platform,
      createTime: data.createTime,
      content: '您已撤回一条消息',
      withdrawContent: data.realContent || data.content,
      withdrawContentNew: data.contentNew || data.contentNew, // 敏感词原句
      withdrawContentType: data.contentType
    }
    let lastMessageFlag = false
    let lastMessageObj: any = {}
    if (currentSession) {
      this.webchatMessage.webchat_todo[data.sessionId].forEach((item: any, index: number) => {
        if (item._id === data._id) {
          const num = parseInt(deepClone(currentSession.length), 0) - 1
          if (num === index) {
            lastMessageFlag = true
          }
          this.webchatMessage.webchat_todo[data.sessionId].splice(index, 1, systemObj)
          let lastMessageIndex = 1
          if (this.webchatMessage.webchat_todo[data.sessionId][index - 1]) {
            if (['system', 'csrInvite', 'csrSubmit', 'withdrawMsg'].includes(this.webchatMessage.webchat_todo[data.sessionId][index - 1].type)) {
              lastMessageIndex++
            }
          }
          if (index > 0) {
            lastMessageObj = this.webchatMessage.webchat_todo[data.sessionId][index - lastMessageIndex]
          }
        }
      })
      if (lastMessageFlag) {
        const currentWebchatList = this.webchatList.webchat_todo
        if (currentWebchatList) {
          currentWebchatList.forEach((item: any, index: number) => {
            if (item._id === data.sessionId) { // 找到当前的会话
              const lastMessage = { contentType: 'text', content: '撤回一条消息', lastMessageFrom: 'withrawMsg' }
              Vue.set(item, 'lastMessage', lastMessage) // 更新卡片最后一条消息
              if (JSON.stringify(lastMessageObj) !== '{}' && lastMessageObj.type === 'in') { // 最后一条消息是访客发送的时候才重新计算访客等待时长
                Vue.set(item, 'visitorStartWaitTimestamp', lastMessageObj.visitorStartWaitTimestamp || lastMessageObj.createTimestamp) // 更新访客等待时长
              }
            }
          })
        }
      }
    }
  }

  @Mutation
  public SET_UNREAD_MESSAGE (type: string) {
    if (type === 'add') {
      this.unreadmessages = this.unreadmessages + 1
    } else {
      this.unreadmessages = 0
      this.unreadmessagesid = ''
    }
  }

  @Mutation
  public SET_MSG_BOX_SCROLL_BOTTOM (scrollBottom: any) {
    this.msgBoxScrollBottom = scrollBottom || 0;
  }

  @Mutation
  public EMPTY_UNREAD_MESSAGE_DISTANCE (distance: any) {
    if (distance < -70) {
      this.unreadmessages = 0
      this.unreadmessagesid = ''
    }
  }

  @Mutation
  public SET_UNREAD_MESSAGESID (ID: any) {
    this.unreadmessagesid = ID;
  }

  @Mutation
  public SET_UNREADMESSAGE (unreadmessages: any) {
    this.unreadmessages = unreadmessages;
  }

  @Mutation
  public SET_AGENT_DATA (data: {} | null) { // 设置智能辅助数据
    this.agentData = data
  }
}

export const WebchatModule = getModule(Webchat)
